
/**
* @file test_list.c
* @brief 内核链表测试
* @author zshare
* @version v1.0
* @date 2022-02-14
* @history  
*/

#include <linux/module.h>//对应内核源码中include/linux/module.h
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>	//包含了module_init和module_exit的声明
#include <linux/cdev.h>	//包含字符设备操作函数
#include <linux/fs.h>	//包含文件接口操作函数
#include <linux/uaccess.h>	//
#include <asm/atomic.h>
#include <linux/slab.h>

#define _log_
#ifdef _log_
	#define kernel_print(format, arg...) printk(format,## arg)
#else
	#define kernel_print(format, arg...) do{}while(0)
#endif
#define VERSION "V1.0"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#define nil NULL
#define FALSE 1
#define TRUE 0
#define pcalloc(x,size,type) do{ if((x = (type *)kcalloc(1,size,GFP_KERNEL)) == nil){ return FALSE; } }while(0)
#define pfree(ptr) do{ if(ptr != nil) { kfree(ptr); } ptr = nil; }while(0)

//一个身份节点
typedef struct {
	u32 id;//成员id
	u8 name[16];//成员名字
	u8 text[32];//成员hash标识
	struct list_head node;//定义一个链表节点
}id_st;

u32 init_id_node(u8 *name, u8 *text, id_st **pid){
	static u32 id = 0;
	id_st *ptmp = nil;
	//申请一个身份节点
	pcalloc(ptmp, sizeof(id_st), id_st);
	//给节点赋值
	ptmp->id = ++id;
	memcpy(ptmp->name, name, 16);
	memcpy(ptmp->text, text, 31);
	//初始化链表节点
	INIT_LIST_HEAD(&ptmp->node);
	(*pid) = ptmp;
	return 0;
}

//打印链表
void print_list(const struct list_head *plist){
	id_st *pos = nil;
	do{
		if(list_empty(plist)){ kernel_print("\t链表为空!\n"); break; }
		//对链表进行遍历操作并打印数据域
		list_for_each_entry(pos, plist, node){
			kernel_print("\t[%d]:%s,%s.\n", pos->id, pos->name, pos->text);
		}
	}while(0);
}

static int __init tlist_init(void){
	int ret = -1;
	id_st *a = nil;
	id_st *b = nil;
	id_st *c = nil;

	//定义一个身份链表
	struct list_head id_list;
	//初始化3个身份节点,分别是A,B,C
	ret = init_id_node("AAAAAAAAAAAAAAA", "a hash value", &a);
	ret = init_id_node("BBBBBBBBBBBBBBB", "b hash value", &b);
	ret = init_id_node("CCCCCCCCCCCCCCC", "c hash value", &c);

	/*==========链表测试开始==========*/
	//初始化链表
	INIT_LIST_HEAD(&id_list);
	//将三个节点采用头插插入链表
	list_add(&a->node, &id_list);
	list_add(&b->node, &id_list);
	list_add(&c->node, &id_list);
	//打印
	kernel_print("插入三个成员后:\n");
	print_list(&id_list);

	//删除b节点再打印
	list_del(&b->node);
	//再打印
	kernel_print("删除b成员后:\n");
	print_list(&id_list);
	//注意需要释放掉删除的节点
	pfree(b);
	
	//删除a节点再打印
	list_del(&a->node);
	//再打印
	kernel_print("删除a成员后:\n");
	print_list(&id_list);
	//注意需要释放掉删除的节点
	pfree(a);

	//删除c节点再打印
	list_del(&c->node);
	//再打印
	kernel_print("删除c成员后:\n");
	print_list(&id_list);
	//注意需要释放掉删除的节点
	pfree(c);

	return ret;
}

static void __exit tlist_exit(void){

}

module_init(tlist_init);
module_exit(tlist_exit);

MODULE_LICENSE("GPL");//软件代码接受的许可协议General Public License
MODULE_AUTHOR("Share");//声明作者
MODULE_DESCRIPTION("A test list module");//模块简单的描述
MODULE_VERSION(VERSION);//模块版本
MODULE_ALIAS("tlist");//模块在用户空间的别名






















